package com.cygsunri.consumption.service;

import com.alibaba.fastjson.JSONArray;
import com.cygsunri.common.constant.DevicePsrId;
import com.cygsunri.common.service.CommonDataService;
import com.cygsunri.consumption.entity.Branch;
import com.cygsunri.consumption.entity.Building;
import com.cygsunri.consumption.entity.EnergyItem;
import com.cygsunri.consumption.entity.request.NewAnalysisRequest;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.util.DateUtil;
import com.cygsunri.util.TimeUtil;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.series.Line;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class ConsumptionAnalysisService {

    @Autowired
    private BranchService branchService;

    @Autowired
    private CommonDataService commonDataService;

    @Autowired
    private BuildingService buildingService;

    @Autowired
    private EnergyItemService energyItemService;

    /**
     * 能耗分析图表
     * 获取分支能耗option
     */
    public Option getBranchAnalysis(Option option, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<Branch> branches = new ArrayList<>();
        for (String id : newAnalysisRequest.getCheckedKeys()) {
            Branch branch = branchService.getBranchById(id);
            if (branch != null) {
                branches.add(branch);
                Line line = new Line(branch.getName());
                option.series(line);
            }
        }

        Line total = new Line("总能耗");
        option.series(total);

        Line comparison = new Line("yoy".equals(newAnalysisRequest.getComparisonType()) ? "同比" : "环比");
        option.series(comparison);

        for (String time : times) {
            option.getxAxis().get(0).data(time);
            int i = 0;
            for (Branch branch : branches) {
                MeasurementValue m = commonDataService.getValue(branch.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                option.getSeries().get(i).data(m.isInValid() ? "-" : format(m.getData()));
                i++;
            }
            MeasurementValue totalM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            option.getSeries().get(i).data(totalM.isInValid() ? "-" : format(totalM.getData()));

            String comparisonTime = "yoy".equals(newAnalysisRequest.getComparisonType()) ? DateUtil.getYoyTime(time) : DateUtil.getPeriodTime(time);
            MeasurementValue comparisonM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(comparisonTime), flag);
            option.getSeries().get(i + 1).data(comparisonM.isInValid() ? "-" : format(comparisonM.getData()));
        }
        return option;
    }

    /**
     * 能耗分析图表
     * 获取建筑能耗option
     */
    public Option getBuildingAnalysis(Option option, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<Building> buildings = new ArrayList<>();
        for (String id : newAnalysisRequest.getCheckedKeys()) {
            Building building = buildingService.getBuildingById(id);
            if (building != null) {
                buildings.add(building);
                Line line = new Line(building.getName());
                option.series(line);
            }
        }

        Line total = new Line("总能耗");
        option.series(total);

        Line comparison = new Line("yoy".equals(newAnalysisRequest.getComparisonType()) ? "同比" : "环比");
        option.series(comparison);

        for (String time : times) {
            option.getxAxis().get(0).data(time);
            int i = 0;
            for (Building building : buildings) {
                MeasurementValue m = commonDataService.getValue(building.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                option.getSeries().get(i).data(m.isInValid() ? "-" : format(m.getData()));
                i++;
            }
            MeasurementValue totalM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            option.getSeries().get(i).data(totalM.isInValid() ? "-" : format(totalM.getData()));

            String comparisonTime = "yoy".equals(newAnalysisRequest.getComparisonType()) ? DateUtil.getYoyTime(time) : DateUtil.getPeriodTime(time);
            MeasurementValue comparisonM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(comparisonTime), flag);
            option.getSeries().get(i + 1).data(comparisonM.isInValid() ? "-" : format(comparisonM.getData()));
        }
        return option;
    }

    /**
     * 能耗分析图表
     * 获取分项能耗option
     */
    public Option getItemAnalysis(Option option, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<EnergyItem> energyItems = new ArrayList<>();
        for (String id : newAnalysisRequest.getCheckedKeys()) {
            EnergyItem energyItem = energyItemService.getEnergyItemById(id);
            if (energyItem != null) {
                Line line = new Line(energyItem.getName());
                option.series(line);
                energyItems.add(energyItem);
            }
        }

        Line total = new Line("总能耗");
        option.series(total);

        Line comparison = new Line("yoy".equals(newAnalysisRequest.getComparisonType()) ? "同比" : "环比");
        option.series(comparison);


        for (String time : times) {
            option.getxAxis().get(0).data(time);
            int i = 0;
            for (EnergyItem energyItem : energyItems) {
                List<Branch> branches = branchService.getBranchesByBuildingAndEnergyItem(newAnalysisRequest.getBuildingId(), energyItem.getId());
                Double sum = 0d;
                for (Branch branch : branches) {
                    MeasurementValue m = commonDataService.getValue(branch.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                    sum += m.isInValid() ? 0d : m.getData();
                }
                option.getSeries().get(i).data(sum);
                i++;
            }
            MeasurementValue totalM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            option.getSeries().get(i).data(totalM.isInValid() ? "-" : format(totalM.getData()));

            String comparisonTime = "yoy".equals(newAnalysisRequest.getComparisonType()) ? DateUtil.getYoyTime(time) : DateUtil.getPeriodTime(time);
            MeasurementValue comparisonM = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(comparisonTime), flag);
            option.getSeries().get(i + 1).data(comparisonM.isInValid() ? "-" : format(comparisonM.getData()));
        }
        return option;
    }

    /**
     * 能耗分析表格
     * 获取分支能耗JSON
     */
    public JSONArray getBranchAnalysisTable(JSONArray jsonArray, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<Branch> branches = branchService.getBranchesByBuildingAndEnergySort(newAnalysisRequest.getBuildingId(), newAnalysisRequest.getEnergySort());
        for (Branch branch : branches) {
            List<Double> values = Lists.newArrayList();
            jsonArray.add(new HashMap<String, Object>(3) {{
                put("id", branch.getId());
                put("name", branch.getName());
                put("data", values);
            }});
            Double total = 0d;
            for (String time : times) {
                MeasurementValue m = commonDataService.getValue(branch.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                values.add(m.isInValid() ? Double.NaN : m.getData());
                total += m.isInValid() ? 0d : m.getData();
            }
            values.add(total);
        }

        List<Double> totalValues = Lists.newArrayList();
        jsonArray.add(new HashMap<String, Object>(3) {{
            put("id", "total");
            put("name", "总能耗");
            put("data", totalValues);
        }});
        Double totalSum = 0d;
        for (String time : times) {
            MeasurementValue m = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            totalValues.add(m.isInValid() ? Double.NaN : m.getData());
            totalSum += m.isInValid() ? 0d : m.getData();
        }
        totalValues.add(totalSum);

        return jsonArray;
    }

    /**
     * 能耗分析表格
     * 获取分项能耗JSON
     */
    public JSONArray getItemAnalysisTable(JSONArray jsonArray, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<EnergyItem> energyItems = energyItemService.getEnergyItemByBuildingAndEnergySort(newAnalysisRequest.getBuildingId(), newAnalysisRequest.getEnergySort());
        for (EnergyItem energyItem : energyItems){
            List<Double> values = Lists.newArrayList();
            jsonArray.add(new HashMap<String, Object>(3) {{
                put("id", energyItem.getId());
                put("name", energyItem.getName());
                put("data", values);
            }});
            List<Branch> branches = branchService.getBranchesByBuildingAndEnergyItem(newAnalysisRequest.getBuildingId(), energyItem.getId());
            Double branchSum = 0d;
            Double total = 0d;
            for (String time : times) {
                for (Branch branch : branches) {
                    MeasurementValue m = commonDataService.getValue(branch.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                    branchSum += m.isInValid() ? 0d : m.getData();
                }
                total += branchSum;
                values.add(branchSum);
            }
            values.add(total);
        }
        List<Double> totalValues = Lists.newArrayList();
        jsonArray.add(new HashMap<String, Object>(3) {{
            put("id", "total");
            put("name", "总能耗");
            put("data", totalValues);
        }});
        Double totalSum = 0d;
        for (String time : times) {
            MeasurementValue m = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            totalValues.add(m.isInValid() ? Double.NaN : m.getData());
            totalSum += m.isInValid() ? 0d : m.getData();
        }
        totalValues.add(totalSum);
        return jsonArray;
    }

    /**
     * 能耗分析表格
     * 获取建筑能耗JSON
     */
    public JSONArray getBuildingAnalysisTable(JSONArray jsonArray, NewAnalysisRequest newAnalysisRequest, List<String> times, int flag) {
        List<Building> buildings = buildingService.getAllBuilding();
        for (Building building : buildings) {
            List<Double> values = Lists.newArrayList();
            jsonArray.add(new HashMap<String, Object>(3) {{
                put("id", building.getId());
                put("name", building.getName());
                put("data", values);
            }});
            Double total = 0d;
            for (String time : times) {
                MeasurementValue m = commonDataService.getValue(building.getPsrID(), newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
                values.add(m.isInValid() ? Double.NaN : m.getData());
                total += m.isInValid() ? 0d : m.getData();
            }
            values.add(total);
        }
        List<Double> totalValues = Lists.newArrayList();
        jsonArray.add(new HashMap<String, Object>(3) {{
            put("id", "total");
            put("name", "总能耗");
            put("data", totalValues);
        }});
        Double totalSum = 0d;
        for (String time : times) {
            MeasurementValue m = commonDataService.getValue(DevicePsrId.CONSUMPTION, newAnalysisRequest.getEnergySort(), TimeUtil.toMilliSeconds(time), flag);
            totalValues.add(m.isInValid() ? Double.NaN : m.getData());
            totalSum += m.isInValid() ? 0d : m.getData();
        }
        totalValues.add(totalSum);
        return jsonArray;
    }

    private String format(Double value) {
        return String.format("%.2f", value);
    }
}
